Imports Cdm.DataCore.Budget
Imports System.Collections.Generic


Partial Class Budget_SpendingPlanDownload
    Inherits System.Web.UI.Page


    Private Const C_EFFECTIVE_DATE_RANGE_EXISTING As String = "0"
    Private Const C_EFFECTIVE_DATE_RANGE_NEW As String = "1"

    Private Const C_BLANK_SPENDING_PLAN As String = "0"
    Private Const C_MIN_YEAR As Integer = 1970

    'Objects and variables used by the download process
    Dim currentParticipant As Cdm.DataCore.Entities.Participant
    Dim currentSpendingPlan As Cdm.DataCore.Budget.SpendingPlan
    Dim currentBudget As Cdm.DataCore.Budget.Budget
    Dim currentStartDate As DateTime
    Dim currentEndDate As DateTime

    Protected Sub Page_Load(ByVal sender As Object, _
                            ByVal e As System.EventArgs) _
                            Handles Me.Load

        SetupJavaScript()
        ErrorSummaryDisplay.Visible = False
        ErrorSummaryDisplay.ClearErrors()

        EntityController.SetSubNavTabsFinancial(Me.EditCaseSubNav)
        Me.downloadlinkRow.Visible = True

        SpendingPlanLabel.Text = EntityController.ReplaceDisplayName("Spending Plan")
        SpendingPlanTwoLabel.Text = "Available " + EntityController.ReplaceDisplayName("Spending Plan") + "s:"
        EntityController.SetFinancialTab(Me.FinancialSubName, Me.EditCaseSubNav)
        Dim Participant As New Cdm.DataCore.Entities.Participant()
        Participant = EntityController.GetParticipant()
        If Participant Is Nothing Then
        Else
            ParticipantNameLabel.Text = Participant.DisplayLastNameFirst()
        End If
        
        If Not Page.IsPostBack Then
            BindBudgets()
            AttachJavaScriptAttributes()
            SetDefaults()
        End If

    End Sub

    ''' <summary>
    '''  This procedure checks the value of the application Setting "SpendingPlanDownloadWithoutBudget"
    '''  and sets up the form depending on the values.
    '''          If the value is true:
    '''                     Show the checkbox where a user may select to Enter own budget.
    '''                     Check the checkbox.
    '''                     Add a value on "None" to the list of budgets.  Select it and disable
    '''          if the value is false, or if the app setting is not found:
    '''                      Hide the checkbox and leave unchecked.
    '''                      Do not add a value of "None" to the list of budgets.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub SetDefaults()
        Dim bSetBudget As Boolean
        If Application("SpendingPlanDownloadWithoutBudget") Is Nothing Then
            bSetBudget = False
        Else
            Dim appSetting As String
            appSetting = Application("SpendingPlanDownloadWithoutBudget").ToString()
            If appSetting.ToUpper().Equals("TRUE") Then
                bSetBudget = True
            End If
        End If

        If bSetBudget Then
            Me.tdCheckBox.Visible = True
            Me.AllowBudgetEntryCheckBox.Checked = True
            Me.BudgetsDropDownList.Items.Insert(0, New ListItem("None", "0"))
            Me.BudgetsDropDownList.SelectedIndex = 0
            Me.BudgetsDropDownList.Enabled = False
        Else
            Me.tdCheckBox.Visible = False
            Me.AllowBudgetEntryCheckBox.Checked = False
            Me.BudgetsDropDownList.Enabled = True
        End If


    End Sub

    Private Sub SetupJavaScript()
        EntityController.JavaScriptSetFixedHeight(0)
        EntityController.JavaScriptAddChildDiv(Me.maindiv.ClientID, 80)
        EntityController.JavaScriptAddChildDiv(Me.pageDiv.ClientID, 120)
    End Sub

    Private Sub AttachJavaScriptAttributes()
        Dim functionString As String = String.Format("spendingPlanSelect('{0}','{1}', '{2}')", Me.SpendingPlansDropDownList.ClientID, DateRangeDropDownList.ClientID, Me.effectiveDatePanel.ClientID)
        SpendingPlansDropDownList.Attributes.Add("onchange", functionString)
        functionString = String.Format("effectiveDateSelect('{0}', '{1}')", DateRangeDropDownList.ClientID, Me.effectiveDatePanel.ClientID)
        DateRangeDropDownList.Attributes.Add("onchange", functionString)
        Dim hidePanelString = String.Format("return hideErrorDisplay('{0}','{1}');", Me.ErrorSummaryPanel.ClientID, Me.UploadConfirmPanel.ClientID)
        Me.ConfirmDownloadButton.Attributes.Add("onclick", hidePanelString)
        Me.DownloadButton.Attributes.Add("onclick", hidePanelString)
        Me.AllowBudgetEntryCheckBox.Attributes.Add("onClick", String.Format("setDefaults(this,'{0}','{1}','{2}');", _
                           BudgetsDropDownList.ClientID, Me.DateRangeDropDownList.ClientID, Me.effectiveDatePanel.ClientID))
    End Sub

    Private Sub BindBudgets()
        Me.BudgetsDropDownList.DataSource = Cdm.DataCore.Budget.Budget.ListAllbyParticipantId(EntityController.GetParticipant.ParticipantId())
        Me.BudgetsDropDownList.DataBind()
        SetSelectControlsEnabled(True)
    End Sub

    Private Function GetFMSATaxRate(ByVal spendingPlanId As Integer, ByVal participantObject As Cdm.DataCore.Entities.Participant, ByVal startDate As DateTime) As Double
        Dim fmsaTaxRate As Double
        Try
            If spendingPlanId > 0 Then
                Dim spendingplanObject As Cdm.DataCore.Budget.SpendingPlan = Cdm.DataCore.Budget.SpendingPlan.Retrieve(spendingPlanId)
                If Year(spendingplanObject.StartDate) > 1900 Then
                    fmsaTaxRate = Cdm.DataCore.Budget.FMSATaxRate.RetrieveByFmsaIdAndDate(participantObject.FMSAId, startDate).TaxRate
                Else
                    fmsaTaxRate = Cdm.DataCore.Budget.FMSATaxRate.RetrieveMostCurrentByFmsaId(participantObject.FMSAId).TaxRate
                End If
            Else
                fmsaTaxRate = Cdm.DataCore.Budget.FMSATaxRate.RetrieveMostCurrentByFmsaId(participantObject.FMSAId).TaxRate
            End If

            Return fmsaTaxRate
        Catch
            Return 0
        End Try
    End Function

    Protected Sub EditCaseSubNav_ChangeMenu(ByVal sender As Object, _
                                            ByVal e As System.EventArgs) _
                                            Handles EditCaseSubNav.ChangeMenu

        EntityController.ReturnToCasePersonalPage(EditCaseSubNav)

    End Sub

    Protected Sub DownloadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DownloadButton.Click
        SetSelectControlsEnabled(True)
        Dim versionNumber As Integer
        If ValidateEntries(versionNumber, False) = False Then
            Exit Sub
        Else
            RetrieveSpendingPlan(versionNumber)
        End If

    End Sub

    Private Sub RetrieveSpendingPlan(ByVal versionNumber As Integer)
        Dim spendingPlanId As Integer = SpendingPlansDropDownList.SelectedValue
        Dim budgetId As Integer = BudgetsDropDownList.SelectedValue
        Dim bSetBudgetAsCurrent As Boolean = False

        If budgetId = 0 And Me.SpendingPlansDropDownList.SelectedValue <> C_BLANK_SPENDING_PLAN And _
      Me.DateRangeDropDownList.SelectedValue.Equals(C_EFFECTIVE_DATE_RANGE_EXISTING) Then
            bSetBudgetAsCurrent = True
        End If

        Session("SpendingPlanId") = spendingPlanId
        Dim template As String = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings.Get("TemplateLocation"))
        Dim virtualDirectory = ConfigurationManager.AppSettings.Get("TemplateLocation").Replace("blankpage.xls", "")
        Dim filename As String
        Dim fmsaTaxRate As Double = GetFMSATaxRate(spendingPlanId, EntityController.GetParticipant(), currentStartDate)

        If fmsaTaxRate <= 0 Then
            Dim fmsaTaxError As String
            If EntityController.GetParticipant().FMSAId = 0 Then
                fmsaTaxError = "Please assign a " + EntityController.ReplaceDisplayName("FMSA") + " to the participant."
            Else
                fmsaTaxError = "Please set up a current tax rate for the participant " + EntityController.ReplaceDisplayName("FMSA")
            End If
            ResultLabel.Text = "There was a problem retrieving the " + EntityController.ReplaceDisplayName("Spending Plan") + ".  " + fmsaTaxError

            ResultLabel.Visible = True
            Return
        End If

        'NOTE - probably should change these methods to pass the objects directly
        ' also -- still need to calculate the version, add as parameter
        ' also -- still need to set the support broker label
        ' also -- need to add a parameter about overwriting start and end dates
        ' also -- set Item Code descriptors to false by default
        Dim bSetDefaultItemDates As Boolean = False
        Dim bSetServiceAndItemCodeDescriptors As Boolean = False

        If Me.DateRangeDropDownList.SelectedValue.Equals(C_EFFECTIVE_DATE_RANGE_NEW) Then
            bSetDefaultItemDates = True
        End If

        Try
            bSetServiceAndItemCodeDescriptors = CBool(Application("UseDropdownsForItemAndServiceCodes"))
        Catch ex As Exception
            bSetServiceAndItemCodeDescriptors = False
        End Try

        Dim spName As String = EntityController.ReplaceDisplayName("Spending Plan")

        'Dim bk As GemBox.Spreadsheet.ExcelFile
        Dim spBuilder As New Spreadsheet.SpendingPlan()
        filename = ""
        Try
            Select Case spendingPlanId
                Case 0
                    filename = spBuilder.DownloadBlankTemplate(currentParticipant.ParticipantId, template, currentStartDate, currentEndDate, budgetId, bSetServiceAndItemCodeDescriptors, versionNumber, spName)
                Case Is > 0

                    filename = spBuilder.DownloadSpendingPlan(spendingPlanId, template, currentStartDate, currentEndDate, budgetId, bSetServiceAndItemCodeDescriptors, versionNumber, bSetDefaultItemDates, spName, bSetBudgetAsCurrent)
                Case Else
                    Return
            End Select
        Catch ex As Exception
            ResultLabel.Text = "There was a problem retrieving the " + EntityController.ReplaceDisplayName("Spending Plan") + ". " + ex.Message
            ResultLabel.Visible = True
            Exit Sub
        End Try

        Dim virtualFileName As String = String.Concat(virtualDirectory, filename.Substring(filename.LastIndexOf("\") + 1))

        'If bk Is Nothing Then
        If filename = "" Then
            ResultLabel.Text = "There was a problem retrieving the " + EntityController.ReplaceDisplayName("Spending Plan") + ". Please verify that the Participant has a current Budget."
            ResultLabel.Visible = True
        Else
            SetSelectControlsEnabled(True)
            Me.HyperLinkLiteral.Text = "<span class='labelNoWidth'>File Created.<a href='" + virtualFileName + "' style='font-weight:bold;'>Click Here</a> to see the file.</span>"
            Me.downloadlinkRow.Visible = True
            'Dim file As System.IO.FileInfo = New System.IO.FileInfo(filename)
            'Dim spFileStream As System.IO.FileStream = New IO.FileStream(filename, IO.FileMode.Open)
            'Dim fileSizeString As String = spFileStream.Length.ToString()
            'spFileStream.Close()
            'spFileStream = Nothing
            'ResultLabel.Visible = False
            'Response.Clear()

            Response.ContentType = "application/vnd.ms-excel"
            If (filename.ToLower().EndsWith(".xls")) Then
                Response.AddHeader("Content-Disposition", "attachment;filename=SpendPlanDownLoad.xls")
            Else
                Response.AddHeader("Content-Disposition", "attachment;filename=SpendPlanDownLoad.xlsx")
            End If

            Response.AddHeader("Target", "newwindow")
            'Response.AddHeader("Content-Length", file.Length.ToString())
            'Session("downloadfile") = filename
            'Dim openPage As String = EntityController.FullPath("~/download.aspx")

            'Response.Write("<script language='javascript'>hideErrorDisplay();</script>")
            'Response.Redirect(openPage)

            'bk.SaveXls(Response.OutputStream())
            Response.WriteFile(filename)
            Response.Flush()
            Response.Close()

            'Response.End()
        End If
    End Sub

    ''' <summary>
    ''' Used to 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function SerialDate()
        Return Now.Hour.ToString() + Now.Minute.ToString() + Now.Second.ToString() _
           + Now.Millisecond.ToString()
    End Function
    Private Function ValidateEntries(ByRef versionNumber As Integer, ByVal alreadyConfirmed As Boolean) As Boolean

        Dim bCheckDates As Boolean = True
        currentParticipant = EntityController.GetParticipant()
        If currentParticipant Is Nothing Then
            FormError("Could not retrieve Participant information")
            Return False
        End If

        '---------------------------------------------------------------
        ' If the user selected a Blank Spending Plan, then they need to 
        '         enter the dates into the effective date range.
        ' Also, if user selected New date range,  they need to enter dates.
        '  If user selected a spending plan, and same date range, then they
        '   do not need to enter.
        '---------------------------------------------------------------
        If Me.SpendingPlansDropDownList.SelectedValue <> C_BLANK_SPENDING_PLAN And _
           Me.DateRangeDropDownList.SelectedValue.Equals(C_EFFECTIVE_DATE_RANGE_EXISTING) Then
            bCheckDates = False
        End If

        '----------------------------------------------------------------
        ' If this is a situation where dates need to be entered, verify that
        '  dates are entered, and that end date is later than begin date
        '----------------------------------------------------------------
        If bCheckDates Then
            If (Not IsDate(Me.StartDateInputControl.Value)) Or (Not IsDate(Me.EndDateInputControl.Value)) Then
                FormError("Please enter a valid spending plan start and end date.")
                Return False
            Else
                currentStartDate = CDate(Me.StartDateInputControl.Value)
                currentEndDate = CDate(Me.EndDateInputControl.Value)
                If currentStartDate > currentEndDate Then
                    FormError("Start Date may not be later than the end date.")
                    Return False
                End If
            End If
        End If

        '----------------------------------------------------------------
        '2. verify that a budget exists and was selected in the dropdown
        '----------------------------------------------------------------
        If Me.BudgetsDropDownList.Items.Count = 0 Then
            FormError("Participant does not have a budget.  Please enter a valid budget amount, with a start and end date, before returning to this page.")
            Return False
        End If
        '---------------------------------------------------------------------
        '3., verify that the selected budget has a start date and an end date,
        ' and verify that the budget end date is later than the start date
        '---------------------------------------------------------------------

        Dim budgetId As Integer = CInt(Me.BudgetsDropDownList.SelectedValue)

        If budgetId > 0 Then
            currentBudget = Cdm.DataCore.Budget.Budget.Retrieve(budgetId)
            If currentBudget Is Nothing Then
                FormError("Error Retrieving the Budget.  Can not download.")
                Return False
            Else
                If Year(currentBudget.ExpirationDate) < C_MIN_YEAR Then
                    FormError("This Budget does not have a valid Expiration Date. Please modify the budget in the budget page, then return to this page to get your Spending Plan.")
                    Return False
                End If
                If Year(currentBudget.EffectiveDate) < C_MIN_YEAR Then
                    FormError("This Budget does not have a valid Effective Date. Please modify the budget in the budget page, then return to this page to get your Spending Plan.")
                    Return False
                End If

                If currentBudget.ExpirationDate.CompareTo(currentBudget.EffectiveDate) < 0 Then
                    FormError("This Budget has an effective date that is later than the expiration date.  Please update the budget, then return to this page to download the spending plan.")
                    Return False
                End If
            End If
        Else
            Dim budgetErrorMessage As String = ""
            If Year(currentStartDate) > 1900 Then
                If BudgetExistsWithinDateRanges(budgetErrorMessage) Then
                    FormError(budgetErrorMessage)
                    Return False
                End If
            End If
            End If
            '------------------------------------------------------------------------
            '4.  Verify that the spending plan start and end dates are within
            '    the budget start and end date periods.
            '-------------------------------------------------------------------------
            If Me.SpendingPlansDropDownList.SelectedValue <> C_BLANK_SPENDING_PLAN Then
                currentSpendingPlan = Cdm.DataCore.Budget.SpendingPlan.Retrieve(CInt(Me.SpendingPlansDropDownList.SelectedValue))
                If currentSpendingPlan Is Nothing Then
                    FormError("Unable to retrieve spending plan")
                    Return False
                End If

                If bCheckDates = False Then
                    currentStartDate = currentSpendingPlan.StartDate
                    currentEndDate = currentSpendingPlan.EndDate
                    If Year(currentEndDate) < 1980 Then
                        FormError("The selected spending plan does not have an end date.  Please enter new dates, or go to the spending plans page to assign and end date.")
                        Return False
                    End If
                    If currentStartDate > currentEndDate Then
                        FormError("Spending Plan Start date is later than the end date.  Please update the spending plan.")
                        Return False
                    End If
                End If
            End If


            If Not currentBudget Is Nothing Then
                If currentStartDate < currentBudget.EffectiveDate Or _
                   currentEndDate > currentBudget.ExpirationDate Then
                    Dim msg As String = "The spending plan date range you selected is {0}.  It needs to fall within the selected Budget effective date range.  The budget you selected has an effective range of {1}"
                    Dim spRange As String = currentStartDate.ToShortDateString() + " - " + currentEndDate.ToShortDateString()
                    Dim budRange As String = currentBudget.EffectiveDate.ToShortDateString() + " - " + currentBudget.ExpirationDate.ToShortDateString()
                    FormError(String.Format(msg, spRange, budRange))
                    Return False
                End If
            End If

            If alreadyConfirmed Then
                Return True
            End If

            '5.   verify whether the spending plan start and end dates
            'overlap another spending plan, or match the start date
            'If they match the start date -- then show a confirm message
            Dim errorMessage As String = ""
            Dim ValidateSp As Cdm.DataCore.Budget.SpendingPlan.DateValidationType = Cdm.DataCore.Budget.SpendingPlan.CheckDatesValid(EntityController.GetParticipant().ParticipantId, 0, _
                                    currentStartDate, currentEndDate, 25001, errorMessage, versionNumber)
            'If they overlap, then show 

            Select Case ValidateSp
                Case Cdm.DataCore.Budget.SpendingPlan.DateValidationType.DateMatchesAnotherStartDate
                    ShowConfirmMessage(errorMessage, versionNumber)
                    Return False
                Case Cdm.DataCore.Budget.SpendingPlan.DateValidationType.DatesAreValid
                    Return True
                Case Cdm.DataCore.Budget.SpendingPlan.DateValidationType.DatesOverlap
                    FormError(errorMessage)
                    Return False
            End Select

            Return True
    End Function

    Private Function BudgetExistsWithinDateRanges(ByRef budgetErrorMessage As String) As Boolean
        Dim returnMessage As String = "When selecting the option to enter a budget, the dates entered must not overlap any existing budget.  There is a current budget with a date range of {0} - {1}.  Please modify the date range, or uncheck the check box."

        Dim startDate As DateTime = CDate(Me.StartDateInputControl.Value)
        Dim endDate As DateTime = CDate(Me.EndDateInputControl.Value)

        Dim budgets As IList(Of Budget) = Budget.ListAllbyParticipantId(EntityController.GetParticipant.ParticipantId())
        If budgets Is Nothing Then Return False
        If budgets.Count = 0 Then Return False

        For i As Integer = 0 To budgets.Count - 1
            If budgets(i).ExpirationDate >= startDate And budgets(i).EffectiveDate <= endDate Then
                budgetErrorMessage = String.Format(returnMessage, budgets(i).EffectiveDateDisplay, budgets(i).ExpirationDateDisplay)
                Return True
            End If
        Next

        Return False

    End Function

    Private Sub FormError(ByVal errorMessage As String)
        ErrorSummaryDisplay.SetSingleError(errorMessage)
        ErrorSummaryDisplay.Visible = True
        Me.ErrorSummaryPanel.Visible = True
    End Sub

    Private Sub ShowConfirmMessage(ByVal errorMessage As String, ByVal versionNumber As Integer)
        FormError(errorMessage)
        Me.UploadConfirmPanel.Visible = True
        ViewState("versionNumber") = versionNumber
        SetSelectControlsEnabled(False)
    End Sub

    Protected Sub ConfirmDownloadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ConfirmDownloadButton.Click
        Dim versionNumber As Integer = CInt(ViewState("versionNumber"))
        If ValidateEntries(versionNumber, True) Then
            RetrieveSpendingPlan(versionNumber)
            Me.UploadConfirmPanel.Visible = False
            SetSelectControlsEnabled(True)
        End If
    End Sub

    Protected Sub CanceldownloadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CanceldownloadButton.Click
        Me.UploadConfirmPanel.Visible = False
        SetSelectControlsEnabled(True)
    End Sub

    Private Sub SetSelectControlsEnabled(ByVal bEnabled As Boolean)
        SpendingPlansDropDownList.Enabled = bEnabled
        BudgetsDropDownList.Enabled = bEnabled
        DateRangeDropDownList.Enabled = bEnabled
        effectiveDatePanel.Enabled = bEnabled

        'If they are enabled, apply the rules on what is to be selected
        If bEnabled Then
            If SpendingPlansDropDownList.SelectedValue.Equals(C_BLANK_SPENDING_PLAN) Then
                DateRangeDropDownList.SelectedValue = C_EFFECTIVE_DATE_RANGE_NEW
                DateRangeDropDownList.Enabled = False
            End If


            If DateRangeDropDownList.SelectedValue.Equals(C_EFFECTIVE_DATE_RANGE_EXISTING) Then
                'effectiveDatePanel.Enabled = False
                effectiveDatePanel.Attributes.Add("disabled", "true")
                SetDefaultDatesFromBudget()
            End If


        End If

    End Sub

    Protected Sub BudgetsDropDownList_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles BudgetsDropDownList.SelectedIndexChanged
        SetSelectControlsEnabled(True)
    End Sub

    Private Sub SetDefaultDatesFromBudget()
        Try
            Dim budgetId As Integer = Convert.ToInt32(BudgetsDropDownList.SelectedValue)
            Dim selectedBudget As Cdm.DataCore.Budget.Budget = Cdm.DataCore.Budget.Budget.Retrieve(budgetId)
            If Not selectedBudget Is Nothing Then
                Me.StartDateInputControl.Value = selectedBudget.EffectiveDate.ToShortDateString()
                If IsDate(selectedBudget.ExpirationDate) Then
                    Me.EndDateInputControl.Value = selectedBudget.ExpirationDate.ToShortDateString()
                End If
            End If

        Catch
        End Try
    End Sub
End Class
